package com.yanqu.road.server.gameplayer.module.wingroom;

import com.yanqu.road.dao.impl.wingroom.WingRoomGiveLikeDaoImpl;
import com.yanqu.road.dao.impl.wingroom.WingRoomMessageBaseDaoImpl;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.wingroom.message.UserGiveLikeData;
import com.yanqu.road.entity.wingroom.message.UserWingRoomMessageData;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.pb.wingroom.WingRoomProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.relatives.RelativesModule;
import com.yanqu.road.server.manger.ForbiddenWordMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.wingroom.WingRoomMessageMgr;
import com.yanqu.road.server.pb.WingRoomPb;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.CrossProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.LocalDateTimeHelper;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author ：zfr
 * @date ：2022/3/17 17:01
 */
public class WingRoomMessageModule extends GeneralModule {

    private UserWingRoomMessageData messageData;
    private Map<Integer, List<UserGiveLikeData>> giveLikeMap = new ConcurrentHashMap<>();
    private Map<Integer, List<UserGiveLikeData>> preRecordMap = new ConcurrentHashMap<>();

    public List<UserGiveLikeData> getGiveLikeDataList(int dateMark) {
        List<UserGiveLikeData> list = new ArrayList<>();
        List<UserGiveLikeData> likeDataList = giveLikeMap.get(dateMark);
        if (likeDataList != null) {
            list.addAll(likeDataList);
        }
        List<UserGiveLikeData> preRecordList = preRecordMap.get(dateMark);
        if (preRecordList != null) {
            list.addAll(preRecordList);
        }
        return list;
    }

    public WingRoomMessageModule(GamePlayer player) {
        super(player);
    }

    public void restorePreReduceMessageTimes(int times) {
        if (messageData.getPreReduceMessageTimes() >= times) {
            messageData.setPreReduceMessageTimes(messageData.getPreReduceMessageTimes() - times);
            return;
        }
        messageData.setPreReduceMessageTimes(0);
    }

    @Override
    public boolean loadData() {
        giveLikeMap = new WingRoomGiveLikeDaoImpl().getUserGiveLikeDataMap(getUserId(), getDateMark());
        messageData = new WingRoomMessageBaseDaoImpl().getUserWingRoomMessageData(getUserId());
        initSystem();
        return true;
    }

    @Override
    public void loginSendMsg() {
        syncMsg();
    }

    public void syncMsg() {
        boolean redDot = WingRoomMessageMgr.checkRedDot(getUserId());
        int giveLike = 0;
        List<UserGiveLikeData> userGiveLikeData = giveLikeMap.get(getDateMark());
        List<UserGiveLikeData> preRecordLikeData = preRecordMap.get(getDateMark());
        if (userGiveLikeData != null) {
            giveLike += userGiveLikeData.size();
        }
        if (preRecordLikeData != null) {
            giveLike += preRecordLikeData.size();
        }

        WingRoomProto.UserSelfMessageDataMsg.Builder syncMsg = WingRoomPb.buildSelfMessageDataMsg(messageData, giveLike, redDot);
        player.sendPacket(ClientProtocol.U_WING_ROOM_SELF_MESSAGE_DATA_SYNC, syncMsg);
    }

    public void initMessageData() {
        messageData = new UserWingRoomMessageData();
        messageData.setUserId(getUserId());
        messageData.setTimesResetTime(System.currentTimeMillis());
        messageData.setInsertOption();
    }

    //给人留言
    public void newMessage(long ownerServerId, long ownerUserId, String content, int noteStyle) {
        WingRoomProto.NewMessageRespMsg.Builder respMsg = WingRoomProto.NewMessageRespMsg.newBuilder();
        if (ownerUserId == player.getUserId()) {
            respMsg.setRet(GameErrorCode.E_WING_ROOM_MESSAGE_SELF);
            player.sendPacket(ClientProtocol.U_WING_ROOM_NEW_MESSAGE, respMsg);
            return;
        }
        if (messageData == null) {
            initMessageData();
        }
        if (messageData.getTodayMessageTimes() + messageData.getPreReduceMessageTimes() >= GameConfig.WINGROOM_OTHERS_MESSAGE_NUM) {
            respMsg.setRet(GameErrorCode.E_WING_ROOM_MESSAGE_TIMES_LIMIT);
            player.sendPacket(ClientProtocol.U_WING_ROOM_NEW_MESSAGE, respMsg);
            return;
        }
        content = StringUtils.clearHeadAndTailEmpty(content);
        int stringLen = StringUtils.getStringLen(content);
        if (stringLen > GameConfig.WINGROOM_OTHERS_MESSAGE_WORD_COUNT) {
            respMsg.setRet(GameErrorCode.E_WING_ROOM_MESSAGE_CONTENT_LENGTH_LIMIT);
            player.sendPacket(ClientProtocol.U_WING_ROOM_NEW_MESSAGE, respMsg);
            return;
        }
        if (ForbiddenWordMgr.isForbidden(content)) {
            respMsg.setRet(GameErrorCode.E_FORBIDDEN_WORD);
            player.sendPacket(ClientProtocol.U_WING_ROOM_NEW_MESSAGE, respMsg);
            return;
        }
        if (noteStyle < 1 || noteStyle > GameConfig.WINGROOM_MESSAGE_BASEMAP_NUM) {
            respMsg.setRet(GameErrorCode.E_WING_ROOM_NOTE_STYLE_NO_FOUND);
            player.sendPacket(ClientProtocol.U_WING_ROOM_NEW_MESSAGE, respMsg);
            return;
        }


        Set<Long> relativesIds = player.getModule(RelativesModule.class).getRelativesId();
        //本服
        if (ownerServerId == GameServer.getInstance().getServerId()) {
            respMsg = WingRoomMessageMgr.newMessage(ownerUserId, content, noteStyle, GameServer.getInstance().getServerId(), getUserId(), new ArrayList<>(relativesIds));
            if (respMsg.getRet() == 0) {
                addMessageTimes(1);
            }
            syncMsg();
            player.sendPacket(ClientProtocol.U_WING_ROOM_NEW_MESSAGE, respMsg);
            return;
        }
        //跨服
        messageData.setPreReduceMessageTimes(messageData.getPreReduceMessageTimes() + 1);
        WingRoomProto.NewMessageReqCrossMsg.Builder reqCrossMsg = WingRoomProto.NewMessageReqCrossMsg.newBuilder();
        reqCrossMsg.setOwnerServerId(ownerServerId);
        reqCrossMsg.setOwnerUserId(ownerUserId);
        reqCrossMsg.setContent(content);
        reqCrossMsg.setNoteStyle(noteStyle);
        reqCrossMsg.addAllRelativesIds(relativesIds);
        player.sendPacket(CrossProtocol.C_WING_ROOM_NEW_MESSAGE , reqCrossMsg);
    }

    @Override
    public boolean afterLoadData() {
        return false;
    }

    @Override
    public boolean saveData() {
        for (List<UserGiveLikeData> dataList : giveLikeMap.values()) {
            for (UserGiveLikeData data : dataList) {
                if (data.isInsertOption()) {
                    new WingRoomGiveLikeDaoImpl().add(data);
                }
            }
        }
        if (messageData != null) {
            if (messageData.isInsertOption()) {
                new WingRoomMessageBaseDaoImpl().add(messageData);
            } else if (messageData.isUpdateOption()) {
                new WingRoomMessageBaseDaoImpl().update(messageData);
            }
        }
        return true;
    }

    private int getDateMark() {
        return Integer.valueOf(DateHelper.getPyyyyMMddDateString(System.currentTimeMillis() / 1000));
    }

    public int checkGiveLike(long serverId, long ownerUserId) {
        int dateMark = getDateMark();
        if (giveLikeMap.containsKey(dateMark)) {
            if (giveLikeMap.get(dateMark).size() >= GameConfig.WINGROOM_MESSAGE_LIKE_PEOPLE_NUM) {
                return GameErrorCode.E_WING_ROOM_GIVE_LIKE_TIMES_LIMIT;
            }
            boolean hasLike = giveLikeMap.get(dateMark).stream()
                    .anyMatch(likeData -> likeData.getMessageOwnerServerId() == serverId
                            && likeData.getMessageOwnerUserId() == ownerUserId);
            if (hasLike) {
                return GameErrorCode.E_WING_ROOM_GIVE_LIKE_ALREADY;
            }
        }
        return 0;
    }

    public void addGiveLikeData(long serverId, long ownerUserId) {
        int dateMark = getDateMark();
        UserGiveLikeData data = newGiveLikeData(serverId, ownerUserId, dateMark);
        if (!giveLikeMap.containsKey(dateMark)) {
            giveLikeMap.put(dateMark, new ArrayList<>());
        }
        giveLikeMap.get(dateMark).add(data);
    }

    public void addPreRecordGiveLikeData(long serverId, long ownerUserId) {
        int dateMark = getDateMark();
        UserGiveLikeData data = newGiveLikeData(serverId, ownerUserId, dateMark);
        if (!preRecordMap.containsKey(dateMark)) {
            preRecordMap.put(dateMark, new ArrayList<>());
        }
        preRecordMap.get(dateMark).add(data);
    }

    private UserGiveLikeData newGiveLikeData(long serverId, long ownerUserId, int dateMark) {
        UserGiveLikeData data = new UserGiveLikeData();
        data.setDateMark(dateMark);
        data.setMessageOwnerServerId(serverId);
        data.setMessageOwnerUserId(ownerUserId);
        data.setUserId(getUserId());
        data.setInsertOption();
        return data;
    }

    public void initSystem() {
        if (SystemOpenMgr.systemOpen(player, eSystemId.WingRoom.getValue())) {
            WingRoomMessageMgr.getSelfMessageAllData(player.getUserId(), false);
        }
    }

    public boolean isLikeToday(long ownerServerId, long ownerUserId) {
        int dateMark = getDateMark();
        List<UserGiveLikeData> giveLikeDataList = getGiveLikeDataList(dateMark);
        if (giveLikeDataList != null) {
            return giveLikeDataList.stream()
                    .anyMatch(likeData -> likeData.getMessageOwnerServerId() == ownerServerId
                            && likeData.getMessageOwnerUserId() == ownerUserId);
        }
        return false;
    }

    public void addMessageTimes(int times) {
        messageData.setTodayMessageTimes(messageData.getTodayMessageTimes() + times);
    }

    public void removePreRecord(long ownerServerId, long ownerUserId) {
        int dateMark = getDateMark();
        List<UserGiveLikeData> list = preRecordMap.get(dateMark);
        if (list == null) {
            return;
        }
        for (UserGiveLikeData data : list) {
            if (data.getMessageOwnerServerId() == ownerServerId && data.getMessageOwnerUserId() == ownerUserId) {
                list.remove(data);
                return;
            }
        }
    }

    public void resetOneDay() {
        try {
            long zeroTime = LocalDateTimeHelper.getZeroTimeTimeStamp();
            if (messageData != null) {
                if (messageData.getTimesResetTime() < zeroTime) {
                    messageData.setTodayMessageTimes(0);
                    messageData.setPreReduceMessageTimes(0);
                    messageData.setTimesResetTime(zeroTime);
                }
            }
        } catch (Exception e) {
            log.error("wingRoomMessage refreshTimes reset error, playerId:{}", getUserId(), e);
        }
    }
}
